package com.cencat.common.utils;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.symmetric.AES;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.core.util.IdUtil;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;

/**
 * 加密工具类
 * 提供各种加密算法的封装
 */
@Slf4j
public class EncryptUtils {
    
    private EncryptUtils() {
        // 私有构造器，防止实例化
    }
    
    /**
     * BCrypt加密
     * @param rawPassword 原始密码
     * @return 加密后的密码
     */
    public static String bcryptEncode(String rawPassword) {
        if (StrUtil.isBlank(rawPassword)) {
            throw new IllegalArgumentException("密码不能为空");
        }
        return BCrypt.hashpw(rawPassword);
    }
    
    /**
     * BCrypt验证
     * @param rawPassword 原始密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    public static boolean bcryptMatches(String rawPassword, String encodedPassword) {
        if (StrUtil.isBlank(rawPassword) || StrUtil.isBlank(encodedPassword)) {
            return false;
        }
        return BCrypt.checkpw(rawPassword, encodedPassword);
    }
    
    /**
     * MD5加密
     * @param content 待加密内容
     * @return MD5加密结果
     */
    public static String md5(String content) {
        if (StrUtil.isBlank(content)) {
            return null;
        }
        return DigestUtil.md5Hex(content);
    }
    
    /**
     * SHA256加密
     * @param content 待加密内容
     * @return SHA256加密结果
     */
    public static String sha256(String content) {
        if (StrUtil.isBlank(content)) {
            return null;
        }
        return DigestUtil.sha256Hex(content);
    }
    
    /**
     * AES加密
     * @param content 待加密内容
     * @param key 密钥（16/24/32位）
     * @return 加密后的Base64字符串
     */
    public static String aesEncrypt(String content, String key) {
        if (StrUtil.isBlank(content) || StrUtil.isBlank(key)) {
            return null;
        }
        
        try {
            AES aes = SecureUtil.aes(key.getBytes(StandardCharsets.UTF_8));
            return aes.encryptBase64(content);
        } catch (Exception e) {
            log.error("AES加密失败: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * AES解密
     * @param content 待解密内容
     * @param key 密钥（16/24/32位）
     * @return 解密后的字符串
     */
    public static String aesDecrypt(String content, String key) {
        if (StrUtil.isBlank(content) || StrUtil.isBlank(key)) {
            return null;
        }
        
        try {
            AES aes = SecureUtil.aes(key.getBytes(StandardCharsets.UTF_8));
            return aes.decryptStr(content);
        } catch (Exception e) {
            log.error("AES解密失败: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * 生成RSA密钥对
     * @return 密钥对（公钥和私钥）
     */
    public static KeyPair generateRsaKeyPair() {
        return SecureUtil.generateKeyPair("RSA");
    }
    
    /**
     * RSA公钥加密
     * @param content 待加密内容
     * @param publicKey 公钥
     * @return 加密后的Base64字符串
     */
    public static String rsaEncrypt(String content, String publicKey) {
        if (StrUtil.isBlank(content) || StrUtil.isBlank(publicKey)) {
            return null;
        }
        
        try {
            RSA rsa = new RSA(null, publicKey);
            return rsa.encryptBase64(content, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        } catch (Exception e) {
            log.error("RSA加密失败: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * RSA私钥解密
     * @param content 待解密内容
     * @param privateKey 私钥
     * @return 解密后的字符串
     */
    public static String rsaDecrypt(String content, String privateKey) {
        if (StrUtil.isBlank(content) || StrUtil.isBlank(privateKey)) {
            return null;
        }
        
        try {
            RSA rsa = new RSA(privateKey, null);
            return rsa.decryptStr(content, KeyType.PrivateKey);
        } catch (Exception e) {
            log.error("RSA解密失败: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * Base64编码
     * @param content 待编码内容
     * @return Base64编码结果
     */
    public static String base64Encode(String content) {
        if (StrUtil.isBlank(content)) {
            return null;
        }
        return cn.hutool.core.codec.Base64.encode(content);
    }
    
    /**
     * Base64解码
     * @param content 待解码内容
     * @return Base64解码结果
     */
    public static String base64Decode(String content) {
        if (StrUtil.isBlank(content)) {
            return null;
        }
        return cn.hutool.core.codec.Base64.decodeStr(content);
    }
    
    /**
     * Hex编码
     * @param content 待编码内容
     * @return Hex编码结果
     */
    public static String hexEncode(String content) {
        if (StrUtil.isBlank(content)) {
            return "";
        }
        return HexUtil.encodeHexStr(content.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * Hex解码
     * @param content 待解码内容
     * @return Hex解码结果
     */
    public static String hexDecode(String content) {
        if (StrUtil.isBlank(content)) {
            return "";
        }
        return new String(HexUtil.decodeHex(content), StandardCharsets.UTF_8);
    }
    
    /**
     * 生成随机盐值
     * @param length 盐值长度
     * @return 随机盐值
     */
    public static String generateSalt(int length) {
        return IdUtil.simpleUUID().substring(0, length);
    }
    
    /**
     * 生成API密钥
     * @return API密钥
     */
    public static String generateApiKey() {
        return md5(System.currentTimeMillis() + IdUtil.simpleUUID());
    }
    
    /**
     * 生成访问令牌
     * @return 访问令牌
     */
    public static String generateAccessToken() {
        return sha256(System.currentTimeMillis() + IdUtil.simpleUUID() + IdUtil.simpleUUID());
    }
}